package com.gqz.aircraftwar.mvp.model.aircraft

import android.graphics.*
import com.gqz.aircraftwar.App
import com.gqz.aircraftwar.App.Companion.paint
import com.gqz.aircraftwar.R
import com.gqz.aircraftwar.mvp.model.bomb.BlastManager
import com.gqz.aircraftwar.mvp.model.buff.Buff
import com.gqz.aircraftwar.mvp.model.buff.BuffManager
import com.gqz.aircraftwar.util.MyEnum
import com.gqz.aircraftwar.util.i
import kotlinx.coroutines.*

/**
 * 飞机基类
 *
 * @param name 飞机名称
 * @param appearance 外观
 * @param hp 生命值
 * @param armor 装甲
 * @param speed 速度
 * @param attackSpeed 攻速
 * @param pos 位置
 * @param buff 增益 @TODO
 * @param movable 是否能移动
 * @param path 敌机移动路径
 *
 * @author gqz
 * @data 2020/3/23
 */

open class Aircraft() {
    private val TAG: String = "Aircraft-->"

    var name: String = ""
    var appearance: Bitmap
    var hp: Float = 1f
    var armor: Int = 1
    var speed: Float = 1.0f
    var attackSpeed = 1f
    var pos = PointF(0f, 0f)
    var movable = false
    var dir = MyEnum.Dir.down
    var type = MyEnum.EnemyType.common
    var buffs = arrayListOf<Buff>()
    var free = true

    var move_x = 0f
    var move_y = 0f
    var atk_interval = 1000L

    var bmpArrCol = 5
    var bmpArrRow = 5
    var bmpArr = Array(bmpArrRow) { arrayOfNulls<Rect>(bmpArrCol) }

    init {
        appearance =
            BitmapFactory.decodeResource(App.instance.resources, R.drawable.plane)

        var pieceW = appearance.width / bmpArrCol
        var pieceH = appearance.height / bmpArrRow
        for (a in 0 until bmpArrCol * bmpArrRow) {
            var i = a / bmpArrRow
            var j = a % bmpArrCol
            var l = j * pieceW
            var t = i * pieceH
            var r = l + pieceW
            var b = t + pieceH
            bmpArr[i][j] = Rect(l, t, r, b)
        }
    }

    fun refreshAtkInterval() {
        atk_interval = (1000f / attackSpeed).toLong()
    }

    fun centerX(): Float {
        return pos.x + appearance.width / 2
    }

    inline fun inBounds(): Boolean {
        return App.bounds?.contains(pos.x, pos.y) ?: false
    }

    fun dead() {
        hp = 0f
        free = true
        movable = false
        buffs.clear()
        BlastManager.instance.generateBlast(pos)
        if (type == MyEnum.EnemyType.elite || type == MyEnum.EnemyType.boss) {
            BuffManager.instance.generateBuff(pos)
        }
    }

    /**
     * 获取矩形
     */
    internal inline fun getRect(): RectF {
        var w = appearance.width / 5
        var h = appearance.height / 5
        return RectF(
            pos.x + w, pos.y + h, pos.x + appearance.width - w,
            pos.y + appearance.height - h
        )
    }

    fun addBuff(buff: Buff) {
        buffs.add2(buff)
    }

    fun checkBuff() {
        buffs.filter { it.isOver }.forEach { buffs.remove2(it) }
    }

    fun containBuff(type: MyEnum.BuffType): Boolean {
        buffs.filter { it.type == type }.forEach { return true }
        return false
    }

    /**
     * 添加buff，若当前有相同类型的buff则时间延长，没有则新增
     */
    fun ArrayList<Buff>.add2(buff: Buff) {
        var noSame = true
        buffs.forEach {
            if (it.type == buff.type) {
                noSame = false
                it.duration += buff.duration
            }
        }
        if (noSame) {
            add(buff)
            buff.buff(this@Aircraft)
            i(TAG, "add2--> got a ${buff.type.name} buff")
            i(TAG, "add2--> attackSpeed = $attackSpeed")
        }
    }

    fun ArrayList<Buff>.remove2(buff: Buff): Boolean {
        if (this.contains(buff)) {
            remove(buff)
            buff.relieveBuff(this@Aircraft)
            i(TAG, "remove2--> ${buff.type.name} buff is over")
            return true
        }
        return false
    }

    inline protected fun move(x: Float, y: Float) {
        var bounds = RectF(
            0f, 0f, (App.surfaceW - appearance.width).toFloat(),
            (App.surfaceH - appearance.height).toFloat()
        )
        var newPos = PointF(pos.x + x * speed, pos.y + y * speed)

        if (bounds.contains(newPos.x, 1f)) {//contains()当点小于边界值时才为true
            pos.x += x * speed
        } else {
            if (pos.x <= 0f) pos.x = 0f
            else if (pos.x >= bounds.right - 0f) pos.x = bounds.right - 0f
        }
        if (bounds.contains(1f, newPos.y)) {
            pos.y += y * speed
        } else {
            if (pos.y <= 0f) pos.y = 0f
            else if (pos.y >= bounds.bottom - 0f) pos.y = bounds.bottom - 0f
        }
    }

    inline fun draw(canvas: Canvas) {
//        if (dir == MyEnum.Dir.down) {
//            canvas.save()
//            canvas.rotate(180f)
//            canvas.drawBitmap(appearance, pos.x, pos.y, paint)
//            canvas.restore()
//        } else {
        if (!free) {
            canvas.drawBitmap(appearance, pos.x, pos.y, paint)
        }
//        }
        /**
         * 任然绘制完整图片
         * 但碰撞检测要与 bmpArr 中的 piece 检测
         * 且 piece 要加上 pos 的 x,y 坐标
         *
         * 碰撞检测思路:
         * 首先将图片分成n*m的若干块，取出和指定目标相交的n块，
         * 然后判断块中是否有非0的像素值，若有且非0像素点的数量大于该块的一半，则判断为碰撞
         */
//        for (num in bmpArr) {
//            for (j in num) {
//                var bmpRect = Rect(j)
//                var dstRect = RectF(
//                    bmpRect.left + pos.x + 1,
//                    bmpRect.top + pos.y + 1,
//                    bmpRect.right + pos.x,
//                    bmpRect.bottom + pos.y
//                )
//                canvas.drawBitmap(appearance, bmpRect, dstRect, paint)
//                var a = Region(bmpRect)
//                var parr = IntArray(bmpRect.width()*bmpRect.height())
//                appearance.getPixels(
//                    parr,
//                    0,
//                    bmpRect.right.toInt() - bmpRect.left.toInt(),
//                    bmpRect.left.toInt(),
//                    bmpRect.top.toInt(),
//                    bmpRect.right.toInt() - bmpRect.left.toInt(),
//                    bmpRect.bottom.toInt() - bmpRect.top.toInt()
//                )
//                println()
//            }
//        }
    }
}
